#include "TwGrass.h "
#include "../TwEngineDx.h"
#include "../TwTexture.h "


void TwGrass::InitGrass()
{
	m_pDevice = g_Render->GetDevice();
	TwTexture* pkTexutre = g_Render->GetTextureMgr()->CreateTexture("grass0.png");
	m_pDetailTexture =  (LPDIRECT3DTEXTURE9)pkTexutre->GetData();
	
	pkTexutre = g_Render->GetTextureMgr()->CreateTexture("grass.jpg");
	m_pGrassTexture =  (LPDIRECT3DTEXTURE9)pkTexutre->GetData();

	LPD3DXBUFFER errorlog;    // for storing errors

	D3DXCreateEffectFromFile(g_Render->GetDevice(), (LPCSTR)"pass_3d_vegetation_d3d9.fx", 0, 0, 0, 0, &m_pkeffect, &errorlog);

	if(m_pkeffect == NULL)
	{
		::MessageBox(NULL,(LPCSTR)errorlog->GetBufferPointer(),NULL,0);
	}
	m_pkeffect->SetTechnique("T0");
	m_pkeffect->SetTexture("tex_grass",m_pDetailTexture);
	GenerateGrass(100);
}
void TwGrass::GenerateGrass(int nNum)
{
	m_vecGrass.clear();
	m_uiNumTiles = 0;
	for (int n = 0; n < nNum; ++n)
	{
		int nChild = (int)RandomNumberInRange(2,5);
		nChild = clamp(nChild,2,5);
		m_uiNumTiles += nChild;
		TwGrassData  data;
		
		data.m_nAdd = nChild;
		data.m_fHeight = 30*RandomNumberInRange(0.5,1);
		data.m_fWidth  = data.m_fHeight;//50*RandomNumberInRange(0.5,1);
		data.m_nPos.m_nX = 512*RandomNumberInRange(0.5,1) - 256;
		data.m_nPos.m_nY = 512*RandomNumberInRange(0.5,1)- 256;
		data.m_Rotate = RandomNumberInRange(0.5,1);
		m_vecGrass.push_back(data);
	}
	m_uiNumVertices = m_uiNumTiles * 4;
	m_uiNumIndices = m_uiNumTiles * 6;

	GrassVertex *pTerrainVertices = NULL;
	m_pDevice->CreateVertexBuffer( m_uiNumVertices * sizeof(GrassVertex), D3DUSAGE_WRITEONLY,
		GrassVertex::FVF_Flags,D3DPOOL_MANAGED, &m_pTerrainVB,NULL );

	m_pDevice->CreateIndexBuffer( m_uiNumIndices * sizeof(WORD), D3DUSAGE_WRITEONLY, 
		D3DFMT_INDEX16, D3DPOOL_MANAGED, &m_pTerrainIB, NULL );
	m_pTerrainVB->Lock( 0, m_uiNumVertices * sizeof(GrassVertex), (void**)&pTerrainVertices, 0 );

	UINT uiIndex = 0;
	for( UINT y = 0; y < m_uiNumTiles; ++y )
	{
		pTerrainVertices[uiIndex].x =  - 0.5;
		pTerrainVertices[uiIndex].y =  - 0.5;
		pTerrainVertices[uiIndex].z = y;
		uiIndex++;

		pTerrainVertices[uiIndex].x =  0.5;
		pTerrainVertices[uiIndex].y =  -0.5;
		pTerrainVertices[uiIndex].z = y;
		uiIndex++;

		pTerrainVertices[uiIndex].x =  - 0.5;
		pTerrainVertices[uiIndex].y =  0.5;
		pTerrainVertices[uiIndex].z = y;
		uiIndex++;

		pTerrainVertices[uiIndex].x = 0.5;
		pTerrainVertices[uiIndex].y = 0.5;
		pTerrainVertices[uiIndex].z = y;

		uiIndex++;
	}
	m_pTerrainVB->Unlock();

	WORD *pIndices = NULL;
	m_pTerrainIB->Lock( 0, sizeof(WORD) * m_uiNumIndices, (void**)&pIndices, 0 );
	for(unsigned short idx, idxOff, i = 0;i < m_uiNumTiles;++i )
	{
		idx    = i * 6;
		idxOff = i * 4;

		pIndices[idx]   = idxOff + 0; 
		pIndices[idx+1] = idxOff + 3;
		pIndices[idx+2] = idxOff + 1;
		pIndices[idx+3] = idxOff + 0;
		pIndices[idx+4] = idxOff + 2;
		pIndices[idx+5] = idxOff + 3;
	}
	m_pTerrainIB->Unlock();

	float  *pkFloat = new float[m_uiNumTiles*8];
	for (int n = 0,i = 0;  n < m_uiNumTiles && (i < m_vecGrass.size()); ++i)
	{
		for (int m = 0; m < m_vecGrass[i].m_nAdd; ++m)
		{
			pkFloat[n*8 + m*8 + 0] = m_vecGrass[i].m_fWidth;
			pkFloat[n*8 + m*8 + 1] = m_vecGrass[i].m_fHeight;
			pkFloat[n*8 + m*8 + 2] = m_vecGrass[i].m_Rotate + (3.14*m)/m_vecGrass[i].m_nAdd;
			pkFloat[n*8 + m*8 + 3] = m_vecGrass[i].m_nAdd/5.0f;

			pkFloat[n*8 + m*8 + 4] = m_vecGrass[i].m_nPos.m_nX;
			pkFloat[n*8 + m*8 + 5] = m_vecGrass[i].m_nPos.m_nY;
			pkFloat[n*8 + m*8 + 6] = 1;
			pkFloat[n*8 + m*8 + 7] = 1.0f;//m_vecGrass[i].m_nAdd/2.0f;
		}
		n += m_vecGrass[i].m_nAdd;
	}
	//m_pkeffect->SetInt("GRASS_MAX_INT",m_uiNumTiles);
	m_pkeffect->SetFloatArray("grass_param",pkFloat,m_uiNumTiles*8);
	delete []pkFloat;
	pkFloat = NULL;
}
void TwGrass::Update()
{
}
void TwGrass::Render()
{
	if(m_pkeffect == NULL)
		return;
	static float  fTime = 0.001f;
	static float  fSpanTime = 0.0f;
	static float  fLimited = 0.1f;
	static bool   bChange = false;
	static float  fDesFactor = 1.0f;
	fSpanTime += fTime/fDesFactor;
	m_pkeffect->SetFloat("time_k",fSpanTime);
	if((fSpanTime > fLimited))
	{	
		fTime = -RandomNumberInRange(0.002,0.003);
		fLimited = RandomNumberInRange(0.08,0.10);
		fDesFactor = 1.0f;
	}
	else if (fSpanTime < -fLimited)
	{
		fTime = RandomNumberInRange(0.002,0.003);
		fLimited = RandomNumberInRange(0.08,0.12);
		fDesFactor = 1.0f;
	}
	fDesFactor += 0.01f;
	//g_Render->GetDevice()->BeginScene();

	D3DXMATRIXA16 mWorld, matView, mProj;
	m_pDevice->GetTransform(D3DTS_WORLD, &mWorld);
	m_pDevice->GetTransform(D3DTS_VIEW, &matView);
	m_pDevice->GetTransform(D3DTS_PROJECTION, &mProj);

	D3DXMATRIXA16 matworldviewProj = mWorld*matView*mProj;
	m_pkeffect->SetMatrix("mat_wvp", &matworldviewProj);
	g_Render->GetDevice()->SetStreamSource( 0, m_pTerrainVB, 0, sizeof(GrassVertex) );
	
	g_Render->GetDevice()->SetFVF( GrassVertex::FVF_Flags );
	g_Render->GetDevice()->SetIndices( m_pTerrainIB );
	
	
	m_pDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
	//m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
	//m_pDevice->SetRenderState( D3DRS_ALPHATESTENABLE, TRUE );

	m_pkeffect->Begin(NULL, NULL);    
	m_pkeffect->BeginPass(0);   

	g_Render->GetDevice()->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0,m_uiNumTiles*4,0, m_uiNumTiles*2 );

	m_pkeffect->EndPass();    
	m_pkeffect->End();    
	//g_Render->GetDevice()->EndScene();

	//m_pDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
	//m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
 
}

void TwGrass::Destroy()
{
	SAFE_RELEASE(m_pTerrainVB);
	SAFE_RELEASE(m_pTerrainIB);
	SAFE_RELEASE(m_pDetailTexture);
	SAFE_RELEASE(m_pGrassTexture);
	SAFE_RELEASE(m_pTerrainVB);
	m_vecGrass.clear();
}